package com.pai4j.message.core.template;

import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * 模板引擎抽象基类
 * 实现通用的模板处理逻辑
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
public abstract class AbstractTemplateEngine implements TemplateEngine {

    @Override
    public String render(String template, Map<String, Object> context) {
        if (template == null || template.trim().isEmpty()) {
            return "";
        }

        try {
            // 前置处理
            template = preProcess(template);
            context = preProcessContext(context);

            // 执行渲染
            String result = doRender(template, context);

            // 后置处理
            result = postProcess(result);

            return result;

        } catch (Exception e) {
            log.error("模板渲染失败: engine={}, error={}", getName(), e.getMessage(), e);
            return template; // 返回原始模板
        }
    }

    @Override
    public boolean validateTemplate(String template) {
        try {
            render(template, java.util.Collections.emptyMap());
            return true;
        } catch (Exception e) {
            log.warn("模板验证失败: engine={}, error={}", getName(), e.getMessage());
            return false;
        }
    }

    /**
     * 执行渲染（子类实现）
     */
    protected abstract String doRender(String template, Map<String, Object> context);

    /**
     * 模板前置处理
     */
    protected String preProcess(String template) {
        // 默认不做处理
        return template;
    }

    /**
     * 上下文前置处理
     */
    protected Map<String, Object> preProcessContext(Map<String, Object> context) {
        // 默认不做处理
        return context != null ? context : new java.util.HashMap<>();
    }

    /**
     * 结果后置处理
     */
    protected String postProcess(String result) {
        // 默认不做处理
        return result;
    }

    /**
     * 处理异常
     */
    protected String handleException(String template, Exception e) {
        log.error("模板渲染异常: engine={}, template={}, error={}", 
                getName(), template, e.getMessage());
        return template;
    }
}

